package cn.iocoder.yudao.module.ao.service.teacher;

import cn.hutool.core.collection.CollUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.ao.controller.admin.teacher.vo.*;
import cn.iocoder.yudao.module.ao.dal.dataobject.teacher.TeacherDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.ao.dal.mysql.teacher.TeacherMapper;
import cn.iocoder.yudao.module.ao.dal.mysql.vocationalclassschedule.VocationalClassScheduleMapper;
import cn.iocoder.yudao.module.ao.dal.dataobject.vocationalclassschedule.VocationalClassScheduleDO;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.hutool.core.util.StrUtil;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.ao.enums.ErrorCodeConstants.*;

/**
 * 教师信息 Service 实现类
 *
 * @author 禾安
 */
@Service
@Validated
public class TeacherServiceImpl implements TeacherService {

    @Resource
    private TeacherMapper teacherMapper;

    @Resource
    private VocationalClassScheduleMapper vocationalClassScheduleMapper;

    @Override
    public Long createTeacher(TeacherSaveReqVO createReqVO) {
        // 插入
        TeacherDO teacher = BeanUtils.toBean(createReqVO, TeacherDO.class);
        teacherMapper.insert(teacher);

        // 返回
        return teacher.getTeacherId();
    }

    @Override
    public void updateTeacher(TeacherSaveReqVO updateReqVO) {
        // 校验存在
        validateTeacherExists(updateReqVO.getTeacherId());
        // 更新
        TeacherDO updateObj = BeanUtils.toBean(updateReqVO, TeacherDO.class);
        teacherMapper.updateById(updateObj);
    }

    @Override
    public void deleteTeacher(Long id) {
        // 校验存在
        validateTeacherExists(id);
        // 删除
        teacherMapper.deleteById(id);
    }

    @Override
        public void deleteTeacherListByIds(List<Long> ids) {
        // 删除
        teacherMapper.deleteByIds(ids);
        }


    private void validateTeacherExists(Long id) {
        if (teacherMapper.selectById(id) == null) {
            throw exception(TEACHER_NOT_EXISTS);
        }
    }

    @Override
    public TeacherDO getTeacher(Long id) {
        return teacherMapper.selectById(id);
    }

    @Override
    public PageResult<TeacherDO> getTeacherPage(TeacherPageReqVO pageReqVO) {
        return teacherMapper.selectPage(pageReqVO);
    }

    @Override
    public List<String> getTeacherCourses(Long teacherId) {
        TeacherDO teacher = getTeacher(teacherId);
        if (teacher == null) {
            return new ArrayList<>();
        }
        return getTeacherCoursesByName(teacher.getTeacherName());
    }

    @Override
    public List<String> getTeacherCoursesByName(String teacherName) {
        if (StrUtil.isBlank(teacherName)) {
            return new ArrayList<>();
        }

        List<VocationalClassScheduleDO> allSchedules = vocationalClassScheduleMapper.selectList(new LambdaQueryWrapperX<>());
        Set<String> teacherCourses = new HashSet<>();

        for (VocationalClassScheduleDO schedule : allSchedules) {
            extractCoursesFromScheduleField(schedule.getMondayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getTuesdayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getWednesdayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getThursdayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getFridayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getSaturdayCourse(), teacherName, teacherCourses);
            extractCoursesFromScheduleField(schedule.getSundayCourse(), teacherName, teacherCourses);
        }

        return new ArrayList<>(teacherCourses);
    }

    @Override
    public Map<String, Object> getTeacherSchedule(Long teacherId) {
        TeacherDO teacher = getTeacher(teacherId);
        if (teacher == null) {
            return new HashMap<>();
        }

        List<VocationalClassScheduleDO> allSchedules = vocationalClassScheduleMapper.selectList(new LambdaQueryWrapperX<>());

        Map<String, Object> result = new HashMap<>();
        result.put("teacherName", teacher.getTeacherName());
        result.put("major", teacher.getMajor()); // 使用专业字段替代科目字段
        result.put("position", teacher.getPosition()); // 添加职务信息

        // 构建课程表数据结构
        List<Map<String, Object>> scheduleGrid = new ArrayList<>();
        Map<String, Map<String, String>> sectionMap = new HashMap<>();

        for (VocationalClassScheduleDO schedule : allSchedules) {
            String section = schedule.getClassSection();
            if (StrUtil.isBlank(section)) {
                continue;
            }

            Map<String, String> weekCourses = sectionMap.computeIfAbsent(section, k -> new HashMap<>());

            checkAndAddCourse(schedule.getMondayCourse(), teacher.getTeacherName(), "monday", weekCourses, schedule);
            checkAndAddCourse(schedule.getTuesdayCourse(), teacher.getTeacherName(), "tuesday", weekCourses, schedule);
            checkAndAddCourse(schedule.getWednesdayCourse(), teacher.getTeacherName(), "wednesday", weekCourses, schedule);
            checkAndAddCourse(schedule.getThursdayCourse(), teacher.getTeacherName(), "thursday", weekCourses, schedule);
            checkAndAddCourse(schedule.getFridayCourse(), teacher.getTeacherName(), "friday", weekCourses, schedule);
            checkAndAddCourse(schedule.getSaturdayCourse(), teacher.getTeacherName(), "saturday", weekCourses, schedule);
            checkAndAddCourse(schedule.getSundayCourse(), teacher.getTeacherName(), "sunday", weekCourses, schedule);
        }

        // 转换为前端需要的格式，并按时间排序
        List<String> sortedSections = sectionMap.keySet().stream()
            .filter(section -> !sectionMap.get(section).isEmpty())
            .sorted(this::compareSections)
            .collect(java.util.stream.Collectors.toList());

        for (String section : sortedSections) {
            Map<String, String> weekCourses = sectionMap.get(section);
            Map<String, Object> row = new HashMap<>();
            row.put("section", section);
            row.put("monday", weekCourses.get("monday"));
            row.put("tuesday", weekCourses.get("tuesday"));
            row.put("wednesday", weekCourses.get("wednesday"));
            row.put("thursday", weekCourses.get("thursday"));
            row.put("friday", weekCourses.get("friday"));
            row.put("saturday", weekCourses.get("saturday"));
            row.put("sunday", weekCourses.get("sunday"));
            scheduleGrid.add(row);
        }

        result.put("scheduleGrid", scheduleGrid);
        return result;
    }

    /**
     * 比较节次时间，用于排序
     */
    private int compareSections(String section1, String section2) {
        String time1 = extractTimeFromSection(section1);
        String time2 = extractTimeFromSection(section2);

        if (time1 == null && time2 == null) {
            return section1.compareTo(section2);
        }
        if (time1 == null) return 1;
        if (time2 == null) return -1;

        return time1.compareTo(time2);
    }

    /**
     * 从节次字符串中提取时间
     */
    private String extractTimeFromSection(String section) {
        if (StrUtil.isBlank(section)) {
            return null;
        }

        // 匹配时间格式，如 "08:00-08:45" 或 "8:00-8:45"
        Pattern timePattern = Pattern.compile("(\\d{1,2}:\\d{2})");
        Matcher matcher = timePattern.matcher(section);

        if (matcher.find()) {
            String time = matcher.group(1);
            // 标准化时间格式，确保是两位数的小时
            if (time.length() == 4) { // 如 "8:00"
                time = "0" + time;
            }
            return time;
        }

        return null;
    }

    private void extractCoursesFromScheduleField(String courseField, String teacherName, Set<String> teacherCourses) {
        if (StrUtil.isBlank(courseField) || StrUtil.isBlank(teacherName)) {
            return;
        }

        String[] parts = courseField.trim().split("\\s+");
        if (parts.length >= 2) {
            String courseTeacher = parts[1].trim();
            String cleanedTeacher = cleanTeacherName(courseTeacher);
            String cleanedTargetTeacher = cleanTeacherName(teacherName);

            if (StrUtil.equals(cleanedTeacher, cleanedTargetTeacher)) {
                String courseName = parts[0].trim();
                if (StrUtil.isNotBlank(courseName)) {
                    teacherCourses.add(courseName);
                }
            }
        }
    }

    private void checkAndAddCourse(String courseField, String teacherName, String dayOfWeek,
                                   Map<String, String> weekCourses, VocationalClassScheduleDO schedule) {
        if (StrUtil.isBlank(courseField) || StrUtil.isBlank(teacherName)) {
            return;
        }

        String[] parts = courseField.trim().split("\\s+");
        if (parts.length >= 2) {
            String courseTeacher = parts[1].trim();
            String cleanedTeacher = cleanTeacherName(courseTeacher);
            String cleanedTargetTeacher = cleanTeacherName(teacherName);

            if (StrUtil.equals(cleanedTeacher, cleanedTargetTeacher)) {
                String courseName = parts[0].trim();
                String classroom = parts.length >= 3 ? parts[2].trim() : "";
                String className = schedule.getClassName();

                StringBuilder courseInfo = new StringBuilder(courseName);
                if (StrUtil.isNotBlank(className)) {
                    courseInfo.append("\n").append(className);
                }
                if (StrUtil.isNotBlank(classroom)) {
                    courseInfo.append("\n").append(classroom);
                }

                weekCourses.put(dayOfWeek, courseInfo.toString());
            }
        }
    }

    private String cleanTeacherName(String teacherName) {
        if (StrUtil.isBlank(teacherName)) {
            return "";
        }

        String cleaned = teacherName.trim();
        if (cleaned.endsWith("老师")) {
            cleaned = cleaned.substring(0, cleaned.length() - 2);
        } else if (cleaned.endsWith("教师")) {
            cleaned = cleaned.substring(0, cleaned.length() - 2);
        } else if (cleaned.endsWith("讲师")) {
            cleaned = cleaned.substring(0, cleaned.length() - 2);
        } else if (cleaned.endsWith("教授")) {
            cleaned = cleaned.substring(0, cleaned.length() - 2);
        }

        return cleaned.trim();
    }

}